package com.ecommerce.product.repository;

import com.ecommerce.product.entity.Product;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import jakarta.persistence.LockModeType;
import jakarta.persistence.QueryHint;

/**
 * 产品Repository
 */
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

    /**
     * 分页查询产品列表
     * @param pageable 分页参数
     * @return 产品分页
     */
    Page<Product> findAll(Pageable pageable);

    /**
     * 根据ID查找产品并加锁（用于库存扣减）
     * @param productId 产品ID
     * @return 产品
     */
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @QueryHints({@QueryHint(name = "jakarta.persistence.lock.timeout", value = "5000")})
    @Query("SELECT p FROM Product p WHERE p.id = :productId")
    Optional<Product> findByIdWithLock(Long productId);

    /**
     * 减少库存
     * @param productId 产品ID
     * @param quantity 数量
     * @return 更新行数
     */
    @Modifying
    @Query("UPDATE Product p SET p.stock = p.stock - :quantity WHERE p.id = :productId AND p.stock >= :quantity")
    int reduceStock(Long productId, Integer quantity);

    /**
     * 按销量降序获取前N个产品
     * @param limit 限制数量
     * @return 热门产品列表
     */
    @Query("SELECT p FROM Product p ORDER BY p.sales DESC")
    List<Product> findTopNByOrderBySalesDesc(Pageable pageable);

    /**
     * 按名称或描述搜索产品
     * @param keyword 搜索关键词
     * @param pageable 分页参数
     * @return 产品分页
     */
    @Query("SELECT p FROM Product p WHERE LOWER(p.name) LIKE LOWER(CONCAT('%', :keyword, '%')) OR LOWER(p.description) LIKE LOWER(CONCAT('%', :keyword, '%'))")
    Page<Product> findByNameOrDescriptionContainingIgnoreCase(String keyword, Pageable pageable);

    /**
     * 按分类ID查询产品
     * @param categoryId 分类ID
     * @param pageable 分页参数
     * @return 产品分页
     */
    Page<Product> findByCategoryId(Long categoryId, Pageable pageable);
}